package org.marverse.scripting

import java.util.{Map, HashMap}
//import com.google.common.collect.MapMaker
import util.Util._

object ScriptingUtil {
  // import MutableTypedMap for convenience
  type MutableTypedMap[K[T] <: TypedKey[T], V] = org.marverse.util.MutableTypedMap[K, V]
  val MutableTypedMap = org.marverse.util.MutableTypedMap
  type TypedKey[T] = org.marverse.util.TypedKey[T]
  val TypedKey = org.marverse.util.TypedKey
  
  // traversing
  
  implicit val expressionTraverser = new Traverser[Expression, Expression] {
    override def childrenOf(e: Expression) = e.childExpressions
  }
  implicit val uncheckedExpressionTraverser = new Traverser[UncheckedExpression, UncheckedExpression] {
    override def childrenOf(e: UncheckedExpression) = e.childUncheckedExpressions
  }
  
  def hasErrors(e: Expression): Boolean = {
    e.isInstanceOf[ErrorExpression] || 
      (findFirst((e2: Expression) => if (e2.isInstanceOf[ErrorExpression]) Some(()) else None )(e) != None)
  }
  def findErrors(e: Expression): Seq[ErrorExpression] = e match {
    case ee: ErrorExpression => Seq(ee)
    case _ => findAll { findErrors(_: Expression) }(e)
  }
  
  // utility
  
  def typesOfExpressions[T <: Expression](expressions: Seq[T])(implicit ctx: MutableTypedMap[TypedKey, Any]) =
    expressions.map(_.expressionType(ctx))
  
  // S11n
  
  def s11n = Seq[serialization.S11nInfo](InvocationExprS11n_0)
  
}

